﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Input;
using Crm2011.Framework.Connect.Commands;
using Crm2011.Framework.Connect.Controls;
using Infragistics.Win.UltraWinGrid;
using Infragistics.Win.UltraWinToolbars;



namespace Crm2011.Framework.Connect
{
    public partial class ConnectionListView : Form
    {
        public ConnectionListView()
        {
            InitializeComponent();
        }



        private readonly Dictionary<string, ICommand> _commands = new Dictionary<string, ICommand>();



        public void Initialize()
        {
            requeryGrid();

            _commands.Add("toolSelectProfile", new SelectProfileCommand(this));
            _commands.Add("toolEditProfile", new EditProfileCommand(this)); 
            _commands.Add("toolCancelProfile", new CancelProfileCommand(this)); 
            _commands.Add("toolNewProfile", new NewProfileCommand(this));
            _commands.Add("toolDeleteProfile", new DeleteProfileCommand(this));
            timer1.Start();
        }



        private void requeryGrid()
        {
            GridTable.BeginLoadData();
            GridTable.Clear();
            foreach (ConnectionProfile connectionProfile in ConnectionList.Current.Items)
            {
                var newRow = GridTable.NewGridListRow();
                newRow.ConnectionId = connectionProfile.ConnectionId;
                newRow.ConnectionName = connectionProfile.ConnectionName;
                newRow.ConnectionString = connectionProfile.ConnectionString;
                GridTable.AddGridListRow(newRow);
            }
            controlBindingDataSet.GridList.EndLoadData();
        }




        public ConnectionProfile CurrentProfile
        {
            get
            {
                ConnectionProfile result = null;
                if (gridBindingSource.Current != null)
                {
                    ControlBindingDataSet.GridListRow row = getDataRow(gridBindingSource.Current);
                    result = ConnectionList.Current.Items.FirstOrDefault(p => p.ConnectionId == row.ConnectionId);
                }
                return result;
            }
            set
            {
                if (value == null) return;
                bool isNewProfile = ConnectionList.Current.Add(value);
                requeryGrid();

                ControlBindingDataSet.GridListRow currentDataRow 
                    = this.GridTable.FindByConnectionId(value.ConnectionId);

                ultraGrid1.Selected.Rows.Clear();
                UltraGridRow ultraGridRow = getUltraGridRow( currentDataRow);
                ultraGrid1.ActiveRow = ultraGridRow;
                ultraGridRow.Selected = true;
            }
        }




        public IEnumerable<ControlBindingDataSet.GridListRow> SelectedItems
        {
            get
            {
                List<ControlBindingDataSet.GridListRow> result
                    = (from UltraGridRow selectedRow in this.ultraGrid1.Selected.Rows select getDataRow(selectedRow)).ToList();

                if (!result.Any() && gridBindingSource.Current != null)
                {
                    // nothing selected, do we have a current instead?
                    result.Add(getDataRow(gridBindingSource.Current));
                }
                return result;
            }
        }


        public void DeleteSelectedItems()
        {
            foreach (ControlBindingDataSet.GridListRow gridListRow in this.SelectedItems)
            {
                ConnectionList.Current.Delete( gridListRow.ConnectionId);
            } 
            requeryGrid();
        }



        /// <summary>
        /// Get the DataTable that is bound to the Grid.
        /// </summary>
        private ControlBindingDataSet.GridListDataTable GridTable
        {
            get { return controlBindingDataSet.GridList; }
        }



        private UltraGridRow getUltraGridRow(object gridDataRow)
        {
            return ultraGrid1.Rows.FirstOrDefault(ugr => gridDataRow.Equals(getDataRow(ugr)));
        }



        private ControlBindingDataSet.GridListRow getDataRow(UltraGridRow ultraGridRow)
        {
            return getDataRow(ultraGridRow.ListObject);
        }



        private ControlBindingDataSet.GridListRow getDataRow(object listObject)
        {
            return getDataRow((DataRowView) listObject);
        }



        private ControlBindingDataSet.GridListRow getDataRow(DataRowView rowView)
        {
            return (ControlBindingDataSet.GridListRow) rowView.Row;
        }




        /// <summary>
        /// Check the ICommand CaneExecute properties on a regular basis..
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void timer1Tick(object sender, EventArgs e)
        {
            foreach (KeyValuePair<string, ICommand> keyValuePair in _commands)
            {
                bool canExecute = keyValuePair.Value.CanExecute(null);
                this.ultraToolbarsManager1.Tools[keyValuePair.Key].SharedProps.Enabled = canExecute;
            }
        }



        private void ultraToolbarsManager1ToolClick(object sender, ToolClickEventArgs e)
        {
            try
            {
                ICommand command = _commands[e.Tool.Key];
                if (command.CanExecute(null)) command.Execute(this);
            }
            catch (Exception ex)
            {
                Trace.Default.LogException(ex);
            }
        }

        private void ultraGrid1DoubleClick(object sender, EventArgs e)
        {
            KeyValuePair<string, ICommand> defaultCommand = _commands.FirstOrDefault(c => c.Key == "toolSelectProfile");
            if (defaultCommand.Value.CanExecute(null)) defaultCommand.Value.Execute(this);
        }
    }
}